package com.gobuy.system.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gobuy.system.utils.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author Gaozexi on 2020/6/4 9:30
 * Step by Step  and Stand on,  You Are The Best Investment!
 */

/**
 * 获取客户端的ip
 *
 * @author GaoZeXi
 */
@Component
public class IpFilter implements GlobalFilter, Ordered {
    @Autowired
    private RedisTemplate redisTemplate;
    private Logger logger = LoggerFactory.getLogger(IpFilter.class);
    /**
     * 限制 配置文件的ip 访问
     * 过滤器具体的功能实现,
     * 思路
     * 读取本地配置的黑名单 ip 地址,到redis中 black-items-ip :key import:value ip   ,
     * 用工具类获取的前来访问的ip 比较,true 拦截,false 放行
     * <p>
     * 规则 1 对同一个url访问超过一定次数  秒/3次
     * 智能拦截
     *key =www.baidu.com  value=[]
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        logger.warn("\t\t\t\t[Watch Dog]====>Monitoring illegal IP====Start=====");
         String ipAddr = IpUtil.getIpAddress(exchange.getRequest());
         if("0:0:0:0:0:0:0:1".equals(ipAddr)){
             ipAddr="127.0.0.1";
         }
         //解析黑名单,获取所有的ip 存在
        Set keys = redisTemplate.opsForHash().keys("black-ip-items");
        ObjectMapper objectMapper =new ObjectMapper();
        for (Object key : keys) {
            String ipstr = (String) redisTemplate.opsForHash().get("black-ip-items", key);

            List<String> ips = null;
            try {
                ips = (List<String>) objectMapper.readValue(ipstr,List.class);
            } catch (IOException e) {
                System.out.println("JSON转换异常");
                e.printStackTrace();
            }
            logger.warn(key+"  "+ ips );
            for (String ip : ips) {
                //如果访问的ip  在黑名单内,禁止
                if(ip.equals(ipAddr)){
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                    logger.warn("\t\t\t\t\t\t[Watch Dog]====>Woof, Woof,Woof  ILLEGAL IP!  Do " +
                            "Filter  "+
                            "["+ipAddr+"]" );
                    return response.setComplete();
                }
            }
        }
        System.out.println("LEGAL IP ,DO NEXT---> ");
        return chain.filter(exchange);
    }

    /**
     * 过滤器的执行顺序，
     *
     * @return 返回值小的优先执行
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
